<?php
/*
Aurus CMS - free OOP CMS
Copyright (C) 2010  Nestor Yanchuk

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
if (! defined('ROOT')) die();
/**
 * Клас для відправки пошти з сайту
 * 
 * @package Aurus
 * @author Kvis
 * @copyright 2010
 * @version 1.0
 * @access public
 */
class Email implements Core {
	/**
	 * Return an instance of class
	 *
	 * @return Email
	 */
	public static function getInstance(){
		return Factory::get(__CLASS__);
	}
	/**
	 * метод відправки листів.
	 * Через стандартну функцію mail() чи через протокол SMTP
	 *
	 * @var string
	 */
	public $method = 'mail';//mail or smpt

	/**
	 * Конфігурація для відправки через протокол SMTP
	 * 
	 * address - адреса сервера
	 * port - порт до сервера
	 * login - логін до сервера
	 * pass - до сервера
	 * auth - виставляється саме, самому не чіпати(!!!)
	 *
	 * @var array
	 */
	public $smtpConfig = array(
	'address'	=>	'',
	'port'		=>	25,
	'login'		=>	'',
	'pass'		=>	'',
	'auth'		=>	true,
	);

	/**
	 * Адреса адміністратора сайту
	 *
	 * @var string
	 */
	public $sender = '';

	/**
	 * Кодування листа, за замовчуванням - UTF-8
	 *
	 * @var string
	 */
	public $charset = 'UTF-8';

	/**
	 * headers які будуть додані до листа
	 *
	 * @var string
	 */
	private $headers = '';

	/**
	 * Текст повідомлення
	 *
	 * @var string
	 */
	private $message = '';

	/**
	 * Адреса одержувача листа
	 *
	 * @var string
	 */
	private $to = '';

	/**
	 * Тема листа
	 *
	 * @var string
	 */
	private $subj = '';

	/**
	 * Ресурс до сокета для відправки повідомленнь
	 *
	 * @var resource
	 */
	private $socket = null;
	/**
	 * Лог роботи скрипту, використовується для відкладки
	 *
	 * @var string
	 */
	private $log = '';

	private $file = '';

	/**
	 * @ignore 
	 */
	const RN = "\r\n";

	/**
	 * Функція відправки емейлу з сайту
	 *
	 * @param string $to   - адреса одержувача
	 * @param string $mess - текст повідомлення
	 * @param string $subj - тема листа
	 */
	public function send($to,$mess,$subj = 'no-reply',$file = null){
		$this->message = $mess;
		$this->to = $to;
		$this->subj = $subj;
		if ($file && is_file($file)) {
			$this->file = $file;
		}
		$this->psend();
	}
	/**
	 * @ignore 
	 */
	private function psend(){
		$un        = strtoupper(uniqid(time()));
		
		$this->headers  = "From: $this->sender\n";
		$this->headers .= "To: $this->to\n";
		$this->headers .= "Subject: $this->subj\n";
		$this->headers .= "X-Mailer: PHPMail Tool\n";
		$this->headers .= "Reply-To: $this->sender\n";
		$this->headers .= "Mime-Version: 1.0\n";
		$this->headers .= "Content-Type:multipart/mixed;";
		$this->headers .= "boundary=\"----------".$un."\"\n\n";
		$this->message  = "------------".$un."\nContent-Type:text/html;\n";
		$this->message .= "Content-Transfer-Encoding: 8bit\n\n$this->message\n\n";
		$this->message .= "------------".$un."\n";
		$this->message .= "Content-Type: application/octet-stream;";
		$this->message .= "name=\"".basename($this->file)."\"\n";
		$this->message .= "Content-Transfer-Encoding:base64\n";
		$this->message .= "Content-Disposition:attachment;";
		$this->message .= "filename=\"".basename($this->file)."\"\n\n";
		$this->message .= chunk_split(base64_encode(file_get_contents($this->file)))."\n";

		if ($this->method == 'mail'){
		//	$this->headers = "From: {$this->sender}".RN;
		//	$this->headers .= "MIME-Version: 1.0".RN;
		//	$this->headers .= "Content-type: text/plain; charset={$this->charset}".RN;
		//	$this->headers .= "X-Mailer: Aurus mail";
			mail($this->to,$this->subj,$this->message,$this->headers);
		} else {
		//	$this->headers = 'From: '.$this->sender.RN;
		//	$this->headers .= 'To: '.$this->to.RN;
		//	$this->headers .= 'Subject: '.$this->subj;
			$this->send_smtp();
		}
	}
	/**
	 * @ignore 
	 */
	private function send_smtp(){
		$this->connect_smtp();

		$headers = str_replace(RN.'.', RN.'..', $this->headers);
		$body    = str_replace(RN.'.', RN.'..', $this->message);
		$body    = $body[0] == '.' ? '.'.$body : $body;

		$this->write_smtp_response($this->socket, 'MAIL FROM:<'.$this->sender.'>');
		$this->write_smtp_response($this->socket, 'RCPT TO: <'.$this->to.'>');
		$this->write_smtp_response($this->socket, 'DATA');
		$this->write_smtp_response($this->socket, $headers);
		$this->write_smtp_response($this->socket, '');
		$this->write_smtp_response($this->socket, $body);
		$this->write_smtp_response($this->socket, '.');
		$this->read_smtp_answer($this->socket);
		$this->close_smtp();
	}
	/**
	 * @ignore 
	 */
	private function connect_smtp(){
		$address = $this->smtpConfig['address'];
		$port = $this->smtpConfig['port'];
		$login = $this->smtpConfig['login'];
		$pass = $this->smtpConfig['pass'];

		$this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die('Can not create socket.');
		if ($this->socket < 0) {
			die('socket_create() failed: '.socket_strerror(socket_last_error())."\n");
		}
		$result = socket_connect($this->socket, $address, $port);
		if ($result == false) {
			die('socket_connect() failed: '.socket_strerror(socket_last_error())."\n");
		}
		$this->read_smtp_answer($this->socket);

		if ($this->smtpConfig['auth']) {
			$this->write_smtp_response($this->socket, 'EHLO '.$address);
			$ch = $this->read_smtp_answer($this->socket);
			$this->write_smtp_response($this->socket, 'AUTH LOGIN');
			$this->read_smtp_answer($this->socket);
			$this->write_smtp_response($this->socket, base64_encode($login));
			$this->read_smtp_answer($this->socket);
			$this->write_smtp_response($this->socket, base64_encode($pass));
			$this->read_smtp_answer($this->socket);
		} else {
			$this->write_smtp_response($this->socket, 'HELO '.$address);
			$this->read_smtp_answer($this->socket);
		}
	}
	/**
	 * @ignore 
	 */
	private function read_smtp_answer($socket) {
		$read = socket_read($this->socket, 1024);
		$this->log .= $read."\r\n";
		if ($read{0} !== '2' && $read{0} !== '3') {
			if (!empty($read)) {
				die('SMTP failed:<br> <b>'.$read."</b>\n".nl2br($this->log));
			} else {
				die('Unknown error'."\n");
			}
		}
		return $read;
	}
	/**
	 * @ignore 
	 */
	private function write_smtp_response($socket, $msg) {
		$msg = $msg."\r\n";
		$this->log .= $msg;
		socket_write($this->socket, $msg, strlen($msg));
	}
	/**
	 * @ignore 
	 */
	private function close_smtp(){
		$this->write_smtp_response($this->socket, 'QUIT');
		$this->read_smtp_answer($this->socket);
	}
}

if (boolean(Config::get('useSmtp','class_email'))) {
	$email->smtpConfig = array(
	'address' => Config::get('smtpHost','class_email'),
	'port' => Config::get('smtpPort','class_email'),
	'login' => Config::get('smtpLogin','class_email'),
	'pass' => Config::get('smtpPass','class_email'),
	'auth' => boolean(Config::get('smtpLogin','class_email')) ? true : false
	);
}